'''
Created on 03/09/2009

@author: eh01
'''
from datastore.resource import Resource, ResourceDict
from runtime.task import Task
from datastore.database import DataStore

DEFAULT_TIMEOUT = 20

class PVTTask(Task):
    
    ECHO = 'echo'
    DOCUMENT_TYPES = 'document_types'
    APPLICATION_LIST = 'application_list'
    ECHO_TEXT = 'Hello, World'
    
    def cb_start(self, method, uri, res, result, context, **kwargs):
        '''
        Implementation of the start method
        '''
        uri_pvt = context.uri('pvt:')
        context.process_all(uri_pvt, get='cb_issue_pvt_request', timeout=DEFAULT_TIMEOUT)     

    def cb_issue_pvt_request(self, method, uri, res, result, context, **kwargs):
        '''
        Callback that responses to pvt requests
        '''
        uri_a2a = context.uri('a2a:')
        uri_spear = context.uri('spear:')
        uri_datastore = context.uri('datastore:')
        uri_time = self.spaces.uri('time:')
        # a dictionary to store all the ws call responses
        context.ws_call_responses = {}
        # environment is the last part of the path
        environment = uri.split2()[-1]
        ds = DataStore(context.spaces.ns)
        access_token = ds.find([(uri_datastore.resource.type, uri_spear.type.pvtaccesstoken)])[0]

        cron_resource = Resource()
        cron_resource.interval = kwargs['timeout']
        timer_uri = context.put(uri_time.timer.collection(True), cron_resource)
        context.get_wait(timer_uri.pop, 'cb_pvt_timeout', timer_uri=timer_uri)
        
        request_res = self.create_lxspearecho_echo_request_data(environment, access_token)
        res_uri = context.put(uri_a2a.ws.LxSpearEcho.echo.collection(True), request_res)
        context.get_wait(res_uri.response, 'cb_parse_lxspearecho_echo_response', timer_uri=timer_uri)
        request_res = self.create_lxspeardocumenttypes_getall_request_data(environment, access_token)
        res_uri = context.put(uri_a2a.ws.LxSpearDocumentTypes.getAll.collection(True), request_res)
        context.get_wait(res_uri.response, 'cb_parse_lxspeardocumenttypes_getall_response', timer_uri=timer_uri)
        request_res = self.create_lxapplicationlist_getall_request_data(environment, access_token)
        res_uri = context.put(uri_a2a.ws.LxSpearApplicationList.getAll.collection(True), request_res)
        context.get_wait(res_uri.response, 'cb_parse_lxspearapplicationlist_getall_response', timer_uri=timer_uri)
                
    def create_lxspearecho_echo_request_data(self, environment, access_token):
        webservice_parameter = ResourceDict()
        echo = [] 
        webservice_parameter.echo = echo 
        access_token_elements = self.create_access_token(access_token)
        accessToken = ResourceDict()        
        accessToken.accessToken = access_token_elements
        input = ResourceDict()
        input.input = PVTTask.ECHO_TEXT
        echo.extend([accessToken, input])
        res = Resource()
        res.data = webservice_parameter
        res.environment = environment        
        return res
        
    def create_lxspeardocumenttypes_getall_request_data(self, environment, access_token):
        webservice_parameter = ResourceDict()
        getAll = []
        webservice_parameter.getAll = getAll 
        access_token_elements = self.create_access_token(access_token)
        accessToken = ResourceDict()        
        accessToken.accessToken = access_token_elements        
        getAll.append(accessToken)
        res = Resource()
        res.data = webservice_parameter
        res.environment = environment
        return res
    
    def create_lxapplicationlist_getall_request_data(self, environment, access_token):
        webservice_parameter = ResourceDict()
        getAll = []
        webservice_parameter['getAll'] = getAll 
        access_token_elements = self.create_access_token(access_token)
        accessToken = ResourceDict()        
        accessToken.accessToken = access_token_elements        
        getAll.append(accessToken)
        res = Resource()
        res.data = webservice_parameter
        res.environment = environment
        return res
                          
    def cb_parse_lxspearecho_echo_response(self, method, uri, res, result, context, **kwargs):
        response = res
        echo_text = response.echoResponse.echoReturn
        context.ws_call_responses[self.ECHO] = echo_text
        return self.try_return_result_to_user(context, False, **kwargs)

    def cb_parse_lxspeardocumenttypes_getall_response(self, method, uri, res, result, context, **kwargs):
        response = res
        document_types = response.getAllResponse.getAllReturn.documentTypes
        context.ws_call_responses[self.DOCUMENT_TYPES] = document_types
        return self.try_return_result_to_user(context, False, **kwargs)
    
    def cb_parse_lxspearapplicationlist_getall_response(self, method, uri, res, result, context, **kwargs):
        response = res
        if 'applications' in response.getAllResponse.getAllReturn.keys():
            applications = response.getAllResponse.getAllReturn.applications
            context.ws_call_responses[self.APPLICATION_LIST] = applications
        else:
            context.ws_call_responses[self.APPLICATION_LIST] = None
        return self.try_return_result_to_user(context, False, **kwargs)

    def cb_pvt_timeout(self, method, uri, res, result, context, **kwargs):
        timer_uri = kwargs['timer_uri']        
        context.delete(timer_uri)
        return self.try_return_result_to_user(context, True, **kwargs)
    
    def try_return_result_to_user(self, context, timeout, **kwargs):
        if timeout:
            res = Resource()
            res.timeout = 'Request to SPEAR Timed Out'
            html_uri = context.uri('html:').template.basic.collection()
            generated_html_uri = context.put(html_uri, res)
            gen_res = context.remove(generated_html_uri)            
            return (True, gen_res)            
        else:
            keys = context.ws_call_responses.keys()
            if self.ECHO in keys and \
                self.DOCUMENT_TYPES in keys and \
                self.APPLICATION_LIST in keys:
                timer_uri = kwargs['timer_uri']        
                context.delete(timer_uri)
                res = Resource()
                res.echo = context.ws_call_responses[self.ECHO]
                res.documenttypes = context.ws_call_responses[self.DOCUMENT_TYPES]
                res.applicationlist = context.ws_call_responses[self.APPLICATION_LIST]
                html_uri = context.uri('html:').template.basic.collection()
                generated_html_uri = context.put(html_uri, res)
                gen_res = context.remove(generated_html_uri)            
                return (True, gen_res)
            
    def create_access_token(self, access_token):
        element_1 = ResourceDict()
        element_1.accessLevel = access_token.spear_user_access_level
        element_2 = ResourceDict()
        element_2.hostId = access_token.spear_user_username
        element_3 = ResourceDict()
        element_3.hostPassword = access_token.spear_user_password
        element_4 = ResourceDict()
        element_4.remoteUser = access_token.spear_user_remote_user
        access_token_list = [element_1, element_2, element_3, element_4]
        return access_token_list